/**
 * Copyright 2007-2008. Chongqing First Information & Network Co., Ltd. All
 * rights reserved. <a>http://www.cqfirst.com.cn</a>
 */
package com.cqcis.uip.base.framework.codec;

import java.io.UnsupportedEncodingException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.util.List;

import com.cqcis.uip.base.framework.utils.ByteBuffer;


/**
 * socket接口标准字节流包打包实现.
 * 规范参照与CRM接口打包规范。
 * 
 * @author huangmy
 * @date   2007-12-14
 */
public class StandardObjectEncoderImpl implements ObjectEncoder {
	private static int[] PACKET_RESERVE = new int[]{0x00, 0x00}; /*两位保留*/	
	private int[] packetHead = new int[]{0x01, 0x02}; /*包头ͷ*/
	private int[] packetTail = new int[]{0xfe, 0xff}; /*包尾*/
	private String sendSysId; // 发送系统ID
	private String recvSysId; // 接收系统ID
	private String password; // 密码
	private String encoding = "UTF-8";
	
    private ByteBuffer packetSocketEncode(ByteBuffer fileBuffer) throws CharacterCodingException, UnsupportedEncodingException {    	
        int length = fileBuffer.limit();                
    	ByteBuffer buffer = ByteBuffer.allocate(22 + length);
    	
    	buffer.setAutoExpand(true);
    	
    	buffer.put((byte)packetHead[0]);
    	buffer.put((byte)packetHead[1]);
    	
    	String checkStr = sendSysId + recvSysId + password;
    	byte[] checkBytes = checkStr.getBytes(encoding);
    	byte[] defaultCheckBytes = new byte[12];
    	System.arraycopy(checkBytes, 0, defaultCheckBytes, 0, 
    			(checkBytes.length > 12) ? 12 : checkBytes.length);// 2位发送系统ID+2位接收系统ID+8位密码
    	
    	buffer.put(defaultCheckBytes);
    	
    	buffer.put((byte)PACKET_RESERVE[0]);
    	buffer.put((byte)PACKET_RESERVE[1]);
    	
    	buffer.putInt(length);    	
    	buffer.put(fileBuffer);
    	
    	buffer.put((byte)packetTail[0]);
    	buffer.put((byte)packetTail[1]);
    	
    	buffer.flip();
    	
    	return buffer;
    }
    
	@SuppressWarnings("unchecked")	
	public ByteBuffer encode(Object message) throws Exception {
		if (!(message instanceof List)) {
			if (message instanceof ByteBuffer) {
				return (ByteBuffer)message;
			}

			if (message instanceof String) {
				return ByteBuffer.wrap(((String)message).getBytes());				
			}
			
			return ByteBuffer.wrap("Invalid Object Format.".getBytes());
		}
		
		return packetEncode((List<String>)message);
	}
	
	private ByteBuffer packetEncode(List<String> xmlList) throws Exception {		
		ByteBuffer fileBuffer = ByteBuffer.allocate(1024);		
		fileBuffer.setAutoExpand(true);
		
		for(String xmlFile : xmlList) {						
			fileBuffer.put(packetXmlEncode(xmlFile));
		}
		
		fileBuffer.flip();
		
		return packetSocketEncode(fileBuffer);		
	}
	
	private ByteBuffer packetXmlEncode(String xmlFile)
			throws CharacterCodingException  {
		ByteBuffer buffer = ByteBuffer.allocate(xmlFile.length() + 10);
		buffer.setAutoExpand(true);
		
		ByteBuffer xmlFileBuffer = ByteBuffer.allocate(1024);
		xmlFileBuffer.setAutoExpand(true);
		/* XML字符串, UTF-8编码 */
		xmlFileBuffer.putString(xmlFile, Charset.forName(encoding).newEncoder()); 
		xmlFileBuffer.flip();
				
		buffer.put((byte)packetHead[0]); /*包头*/
		buffer.put((byte)packetHead[1]); /*包头*/
		
		buffer.put((byte)PACKET_RESERVE[0]);  /*两位保留*/
		buffer.put((byte)PACKET_RESERVE[1]);
		
		buffer.putInt(xmlFileBuffer.limit()); // 长度
		buffer.put(xmlFileBuffer);		 
		
		buffer.put((byte)packetTail[0]); /*包尾ͷ*/
		buffer.put((byte)packetTail[1]); /*包尾ͷ*/
				
		buffer.flip();
		
		return buffer;
	}

	public void setSendSysId(String sendSysId) {
		this.sendSysId = sendSysId;
	}

	public void setRecvSysId(String recvSysId) {
		this.recvSysId = recvSysId;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}	
}
